package handlers

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
)

type WSReq struct {
	Cmd  string      `json:"cmd"`
	Data interface{} `json:"data"`
}

type WSResp struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func Chat(c *gin.Context) {
	userId := c.GetUint("userId")
	var upgrader = websocket.Upgrader{}
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer conn.Close()
	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		var req WSReq
		err = json.Unmarshal(message, &req)
		if err != nil {
			WsResError(conn, 1000, "解析失败")
			continue
		}
		switch req.Cmd {
		case "online":
			go Online(conn, message, int(userId))
		case "send":
			go Send(conn, message)
		default:
			WsResError(conn, 1000, "没有该方法")
		}
		WsResSuccess(conn, "解析成功")
	}
}

type SendS struct {
	ToUserId int    `json:"to_user_id"`
	Message  string `json:"message"`
}

type WSSendReq struct {
	Cmd  string `json:"cmd"`
	Data SendS  `json:"data"`
}

func Send(conn *websocket.Conn, message []byte) {
	var req WSSendReq
	err := json.Unmarshal(message, &req)
	if err != nil {
		WsResError(conn, 20001, "Parsing json failed ")
		return
	}
	if OnlineUser[req.Data.ToUserId] == nil {
		WsResError(conn, 20003, "not online")
		return
	}
	WsResSuccess(OnlineUser[req.Data.ToUserId], req.Data.Message)
	WsResSuccess(conn, "send ok")
}

var OnlineUser = make(map[int]*websocket.Conn)

func Online(conn *websocket.Conn, message []byte, userId int) {
	OnlineUser[userId] = conn
	fmt.Println(OnlineUser)
	WsResSuccess(conn, userId)
}

func WsResError(conn *websocket.Conn, code int, msg string) {
	response := WSResp{
		Code: code,
		Msg:  msg,
		Data: nil,
	}
	marshal, err := json.Marshal(response)
	err = conn.WriteMessage(websocket.TextMessage, marshal)
	if err != nil {
		log.Println("write:", err)
		return
	}
}

func WsResSuccess(conn *websocket.Conn, data interface{}) {
	response := WSResp{
		Code: 0,
		Msg:  "ok",
		Data: data,
	}
	marshal, err := json.Marshal(response)
	err = conn.WriteMessage(websocket.TextMessage, marshal)
	if err != nil {
		log.Println("write:", err)
		return
	}
}
